// This Arduino example demonstrates bidirectional operation of a 
// 28BYJ-48, which is readily available on eBay, using a ULN2003 
// interface board to drive the stepper. The 28BYJ-48 motor is a 4-
// phase, 8-beat motor, geared down by a factor of 68. One bipolar 
// winding is on motor pins 1 & 3 and the other on motor pins 2 & 4. 
// Refer to the manufacturer's documentation of  Changzhou Fulling 
// Motor Co., Ltd., among others.  The step angle is 5.625/64 and the 
// operating Frequency is 100pps. Current draw is 92mA.  In this 
// example, the speed and direction of the stepper motor is determined 
// by adjusting a 1k-ohm potentiometer connected to Arduino pin A2. 
// When the potentiometer is rotated fully counterclockwise, the motor 
// will rotate at full counterclockwise speed. As the potentiometer is 
// rotated clockwise, the motor will continue to slow down until is 
// reaches its minimum speed at the the potentiometer's midpoint value . 
// Once the potentiometer crosses its midpoint, the motor will reverse 
// direction. As the potentiometer is rotated further clockwise, the speed   
// of the motor will increase until it reaches its full clockwise rotation 
// speed when the potentiometer has been rotated fully clockwise.
////////////////////////////////////////////////

#define NoNl     false
#define Nl       true

//declare variables for the motor pins
int motorPin1 = 8;	// Blue   - 28BYJ48 pin 1
int motorPin2 = 9;	// Pink   - 28BYJ48 pin 2
int motorPin3 = 10;	// Yellow - 28BYJ48 pin 3
int motorPin4 = 11;	// Orange - 28BYJ48 pin 4
                        // Red    - 28BYJ48 pin 5 (VCC)

int motorSpeed = 1;     //variable to set stepper speed (1 is hightes speed)

char ch;

boolean forward=true;

//////////////////////////////////////////////////////////////////////////////
void setup() {
  //declare the motor pins as outputs
  pinMode(motorPin1, OUTPUT);
  pinMode(motorPin2, OUTPUT);
  pinMode(motorPin3, OUTPUT);
  pinMode(motorPin4, OUTPUT);
  Serial.begin(9600);
}

//////////////////////////////////////////////////////////////////////////////
void loop(){

    
   static int v = 0;
  
  
  if (Serial.available()) {    
    ch = Serial.read();
    switch(ch) {
      case '0'...'9':
        v = v * 10 + ch - '0';
        break;
      case 'b':
        showln("go counterclockwise(New)=",v); 
        turnMotor(v,forward);
        v=0;
        break;
      case 'd': 
       showln("go clockwise(New)=",v); 
       turnMotor(v,!forward);
       v=0;
       break;
      case 'm':
        showln("motorspeed=",v); 
        motorSpeed=v; 
        v = 0;
        break;
      
    }
  } 
  
}


void releaseMotor() {
  digitalWrite(motorPin1, LOW);
  digitalWrite(motorPin2, LOW);
  digitalWrite(motorPin3, LOW);
  digitalWrite(motorPin4, LOW);
}

//////////////////////////////////////////////////////////////////////////////
//set pins to ULN2003 high in sequence from 1 to 4
//delay "motorSpeed" between each pin setting (to determine speed)
void turnMotor(int numberOfFullTicks, boolean forward) {
  
  for (int currTick=0;currTick<numberOfFullTicks;currTick++) {
    for (byte posOfEight=0;posOfEight<8;posOfEight++) {
          writeMotor(posOfEight,forward);
          delay(motorSpeed);
    }
  }
  releaseMotor();
}


void writeMotor(byte posOfEight, boolean forward) {
  byte motorByte = clockwiseByte(posOfEight);
  if (forward) {
    if (motorByte & 1)      {digitalWrite(motorPin1,HIGH);}
    else                    {digitalWrite(motorPin1,LOW);}
    if ((motorByte & 2)>>1) {digitalWrite(motorPin2,HIGH);}
    else                    {digitalWrite(motorPin2,LOW);}
    if ((motorByte & 4)>>2) {digitalWrite(motorPin3,HIGH);}
    else                    {digitalWrite(motorPin3,LOW);}
    if ((motorByte & 8)>>3) {digitalWrite(motorPin4,HIGH);}
    else                    {digitalWrite(motorPin4,LOW);}
  } else {
    if (motorByte & 1)      {digitalWrite(motorPin4,HIGH);}
    else                    {digitalWrite(motorPin4,LOW);}
    if ((motorByte & 2)>>1) {digitalWrite(motorPin3,HIGH);}
    else                    {digitalWrite(motorPin3,LOW);}
    if ((motorByte & 4)>>2) {digitalWrite(motorPin2,HIGH);}
    else                    {digitalWrite(motorPin2,LOW);}
    if ((motorByte & 8)>>3) {digitalWrite(motorPin1,HIGH);}
    else                    {digitalWrite(motorPin1,LOW);}
  }
}

byte clockwiseByte(byte count) {
  byte pinPos = count/2;  
  byte  pinBelegung = 1<<pinPos;
  if ((count %2)==1) {pinBelegung=pinBelegung + (1<<((pinPos+1)%4));}
  return pinBelegung;
}


void show(char nameStr[], long val) {
     show(nameStr,val, NoNl);
}

void showln(char nameStr[], long val) {
     show(nameStr,val, Nl);
}

void show(char nameStr[], long val, boolean newline) {
  Serial.print(nameStr);  
  if (newline)
       Serial.println(val);
  else Serial.print(val);
}

void show(char nameStr[], long pos,  long val, boolean newline) {
       
      show(nameStr, pos, ":", val, newline);
}

void show(char nameStr[], long pos, char rightStr[],long val, boolean newline) {
  Serial.print(nameStr);  
  Serial.print(pos);
  Serial.print(rightStr);
  if (newline)       
       Serial.println(val);
  else Serial.print(val);
}
